fix(tool-search): use the API's native search tool name and inject only on Anthropic hosts - #1332
Open
JJONGFILM wants to merge 1 commit into
Open
Conversation
…ly on Anthropic hosts
The Anthropic native tool-search adapter appended
`{ type: "tool_search_tool_bm25_20251119", name: "tool_search" }`, but the
Messages API only accepts `name: "tool_search_tool_bm25"` for that type and
rejects the whole request with 400. It was also injected for every
`anthropic-messages` model, so third-party hosts speaking the Anthropic wire
format (Kimi Code, OpenRouter, proxies) answered with an opaque
`400 Invalid request Error`.
- rename the native search tool to `tool_search_tool_bm25`
- pass the request model (`event.model ?? ctx.model`) to the adapter and skip
injection unless the model's baseUrl host is anthropic.com or a subdomain;
a missing baseUrl keeps the previous behaviour
- make the request-validator mock enforce the tool name like the API does and
cover the name, the host gate, and third-party 400 attribution in tests
- record the change in tool-search/changes.md
Surfaced by code-yeongyu#1314: eval-only routing leaves the catalog non-empty for every
session, which turned the adapter on for everyone.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Owner
|
Both defects this PR describes are now fixed on
#1354 also fixed a third defect this PR does not cover: Closing is the owner's call — flagging the overlap so this does not get rebased onto work that already landed. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Two defects in the Anthropic native tool-search adapter (
builtin/tool-search/native-search.ts) that together break everyanthropic-messagesrequest once the extension catalog contains an inactive tool:name. The adapter appended{ type: "tool_search_tool_bm25_20251119", name: "tool_search" }. The Messages API only acceptsname: "tool_search_tool_bm25"for that type and rejects the whole request:anthropic-messagesendpoint. The gate wasapi === "anthropic-messages", so third-party hosts that speak the Anthropic wire format (Kimi Codeapi.kimi.com/coding, OpenRouter, proxies) also received the server-side tool and answered with an opaque400 {"error":{"type":"invalid_request_error","message":"Invalid request Error"}}.Why it surfaced now
The adapter has been in since #811, but
enabled()only fires when the catalog has an inactive extension tool. #1314 (eval-only routing forbash/workflow/monitoras the default) makes that true for every session, so2026.9.3-3turned native injection on for everyone and both defects hit at once. The 400 fallback (noteResponseStatus) only kicks in after the first failed turn of each session and, on third-party hosts, hid the real cause behind a generic error.Changes
ANTHROPIC_TOOL_SEARCH_NAME→"tool_search_tool_bm25".AnthropicNativeToolSearchAdapter.applyBeforeRequest(model, payload)now takes the request model (event.model ?? ctx.model) and skips injection unlessisFirstPartyAnthropicEndpoint(model.baseUrl)— hostnameanthropic.comor a subdomain. A missingbaseUrlkeeps the previous behaviour, so existing callers/tests are unaffected.addAnthropicNativeToolSearchitself is unchanged (still the pureapi+ payload transform).native-search-mocks.ts) now enforces the toolnamethe way the API does, so the old name fails the existing HARD-RULES tests instead of passing silently.test/tool-search/native-anthropic.test.ts: exact tool name, pre-fix name is a 400 in the validator, host classification, and that ananthropic-messagesmodel on a third-party host gets the untouched payload while a later 400 from that host is not attributed to native search.tool-search/changes.mdentry.No
CHANGELOG.mdedit (maintainer-owned).Verification
npx vitest --run test/tool-search test/mcp/tool-search-promotion.test.ts test/mcp/native-anthropic.test.ts— green.npm run check— green.omo-ai 5.0.0-0.beta.38/39(senpi2026.9.3-3), session log excerpts with the two error shapes above againstanthropic/claude-fable-5,anthropic/claude-opus-5, andkimi-coding/k3. Applying the same two changes to the installeddist/restored both providers; the Kimi model keeps working through the localtool_searchtool.Notes for reviewers
api.anthropic.comon a non-anthropic.comhostname loses native tool search with this change and falls back to localtool_search(no request failure). If that should be opt-in-able, acompatflag on the model config would be the natural follow-up; I kept this PR to the minimal fix.Summary by cubic
Fixes the Anthropic native tool-search adapter so requests no longer fail with 400 errors. The injected tool now uses the API-required name
tool_search_tool_bm25, and injection only runs on first-partyanthropic.comhosts; third-party hosts now fall back to the localtool_searchtool.Bug Fixes
tool_search_tool_bm25; the API rejects any other name with a 400.anthropic-messagesmodels on third-party hosts like Kimi Code and OpenRouter, which don't implement native tool search.baseUrlkeep the previous behavior so existing callers and tests are unaffected.Written for commit 475598d. Summary will update on new commits.